﻿using Microsoft.Practices.EnterpriseLibrary.Data.Sql;
using SimpleInjector;
using Sustainalytics.BusinessResearchProductStates.Entities.ResearchState;
using Sustainalytics.ClientDW.Entities;
using Sustainalytics.ClientDW.Synchronization.SyncRiskRatingsData.Events;
using Sustainalytics.Synchronization.Interface;
using Sustainalytics.ClientDW.Synchronization.SyncRiskRatingsData.RiskRatingClusters;
using Sustainalytics.ClientDW.Synchronization.SyncRiskRatingsData.RiskRatingResearchProfileLogic;
using Sustainalytics.Entities;
using Sustainalytics.Entities.RiskRatings;
using Sustainalytics.MongoDB.Extensions;
using System.Collections.Generic;
using System.Configuration.Abstractions;
using Sustainalytics.CDDB.DataConnector;
using Sustainalytics.Entities.Governance;
using Sustainalytics.ClientDW.Synchronization.SyncRiskRatingsData.Helpers;

namespace Sustainalytics.ClientDW.Synchronization.SyncRiskRatingsData
{
    public static class SimpleInjectorConfig
    {
        public static Container Register(ILogger logger, Dictionary<string, string> gaConnectionStrings)
        {
            var container = new Container();

            container.RegisterCollections(gaConnectionStrings);

            container.RegisterMisc(logger);

            container.Verify();

            return container;
        }

        private static void RegisterCollections(this Container container, Dictionary<string, string> gaConnectionStrings)
        {
            var clientDwConnectionString = gaConnectionStrings["ClientDW"];
            var riskRatingsResearchConnectionString = gaConnectionStrings["RiskRatingsResearchDW"];

            container.Register(() => MongoFactory.GetCollectionFromDatabase<CompanyProfileResearchState>(clientDwConnectionString) );
            container.Register(() => MongoFactory.GetCollectionFromDatabase<CorporateData>(clientDwConnectionString));
            container.Register(() => MongoFactory.GetCollectionFromDatabase<RiskRatingResearchProfile>(riskRatingsResearchConnectionString));
            container.Register(() => MongoFactory.GetCollectionFromDatabase<RiskRatingMaterialEsgIssue>(riskRatingsResearchConnectionString));
            container.Register(() => MongoFactory.GetCollectionFromDatabase<RiskRatingCluster>(riskRatingsResearchConnectionString));
            container.Register(() => MongoFactory.GetCollectionFromDatabase<ExposureCluster>(riskRatingsResearchConnectionString));
            container.Register(() => MongoFactory.GetCollectionFromDatabase<ManageableCluster>(riskRatingsResearchConnectionString));
            container.Register(() => MongoFactory.GetCollectionFromDatabase<ManagementCluster>(riskRatingsResearchConnectionString));
            container.Register(() => MongoFactory.GetCollectionFromDatabase<ComprehensiveRiskRatingIndicator>(riskRatingsResearchConnectionString));
            container.Register(() => MongoFactory.GetCollectionFromDatabase<Sustainalytics.Entities.RiskRatings.EventIndicator>(riskRatingsResearchConnectionString));
            container.Register(() => MongoFactory.GetCollectionFromDatabase<Sustainalytics.Entities.RiskRatings.Incident>(riskRatingsResearchConnectionString));
            container.Register(() => MongoFactory.GetCollectionFromDatabase<RiskRatingSource>(riskRatingsResearchConnectionString));
            container.Register(() => MongoFactory.GetCollectionFromDatabase<EventMapping>(riskRatingsResearchConnectionString));
            container.Register(() => MongoFactory.GetCollectionFromDatabase<GovernancePillars>(riskRatingsResearchConnectionString));

            container.Register(() => MongoFactory.GetCollectionFromDatabase<CoreRiskRatingResearchProfile>(riskRatingsResearchConnectionString));
            container.Register(() => MongoFactory.GetCollectionFromDatabase<CoreRiskRatingIndicator>(riskRatingsResearchConnectionString));

            var governanceConnectionString = gaConnectionStrings["GovernanceDW"];
            container.Register(() => MongoFactory.GetCollectionFromDatabase<GovernanceIssue>(governanceConnectionString));
            container.Register(() => MongoFactory.GetCollectionFromDatabase<GovernanceComputationResult>(governanceConnectionString));
        }

        private static void RegisterMisc(this Container container, ILogger logger)
        {
            container.Register(() => logger, Lifestyle.Singleton);
            container.Register<GovernancePillarsHelper>();
            container.Register(typeof(SqlDatabase),()=> new SqlDatabase(ConfigurationManager.Instance.ConnectionStrings["EventsConnectionString"].ConnectionString) );

            container.RegisterSingleton(() => ConfigurationManager.Instance.AppSettings);
            container.RegisterSingleton<BackOfficeAppSettings>();
            container.RegisterSingleton(() => new CorporateDataRepository(container.GetInstance<BackOfficeAppSettings>().ThriftServer,
                                                                            container.GetInstance<BackOfficeAppSettings>().ThriftPort,
                                                                            container.GetInstance<BackOfficeAppSettings>().HbaseTablePrefix,
                                                                            container.GetInstance<BackOfficeAppSettings>().HiveConnectionString));
            container.RegisterSingleton(() => new RiskRatingsDataProvider.RiskRatingsDataProvider(
            new Ai.HbaseRepository.HbaseConfiguration
            {
                ThriftServerAddress = container.GetInstance<BackOfficeAppSettings>().ThriftServer,
                ThriftPort = container.GetInstance<BackOfficeAppSettings>().ThriftPort,
                TablePrefix = container.GetInstance<BackOfficeAppSettings>().HbaseTablePrefix,
            }));
            container.Register<RiskRatingResearchProfileQuery>(Lifestyle.Singleton);
            
            container.Register<RiskRatingClusterQuery>(Lifestyle.Singleton);
            container.RegisterSingleton(() => new SyncCommand(container.GetInstance<CollectionFactory>(),
                                                                logger,
                                                                ConfigurationManager.Instance.AppSettings.AppSetting("InsertManyBatchSize", () => 500)));
        }
    }
}
